#include <bits/stdc++.h>
using namespace std;
const int N=1e5+50;
const int M=2e5+50;
int n,m,u,v;
struct Edge{
    int v,next;
}edge[M];
int cnt,head[N];
void init(){
    cnt=0;
    memset(head,-1,sizeof(head));
}
void addEdge(int u,int v){
    edge[cnt]=Edge{v,head[u]};
    head[u]=cnt++;
}
// i或i的子树能追溯到最早的栈中节点编号
// dfs序
int Low[N],DFN[N],Stack[N],Belong[N];
//dfs序/时间戳  
int idx,top,scc;
bool isStack[N];
int num[N];
void tarjan(int u){
    Low[u]=DFN[u]=++idx;
    Stack[top++]=u;
    isStack[u]=true;
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].v;
        if(!DFN[v]){
            //没访问过
            tarjan(v);
            //子节点信息更新父节点
            Low[u]=min(Low[u],Low[v]);
        }else if(isStack[v]){
            //v已在栈中,更新Low,尽量往上更新
            Low[u]=min(Low[u],DFN[v]);
        }
    }
    //回溯
    //找到一个scc,不断出栈直到等于u,这些点都是强连通分量的点
    if(Low[u]==DFN[u]){
        scc++;
        int v;
        do{
            v=Stack[--top];
            isStack[v]=false;
            Belong[v]=scc;
            num[scc]++;
        }while(v!=u);
    }
}
int main(void){
    while(~scanf("%d%d",&n,&m) && n+m){
        init();
        memset(DFN,0,sizeof(DFN));
        memset(Low,0,sizeof(Low));
        memset(Stack,0,sizeof(Stack));
        memset(isStack,false,sizeof(isStack));
        memset(Belong,0,sizeof(Belong));
        memset(num,0,sizeof(num));
        idx=0;
        top=0;
        scc=0;
        while(m--){
            scanf("%d%d",&u,&v);
            addEdge(u,v);
        }
        for(int i=1;i<=n;i++){
            if(!DFN[i]){
                tarjan(i);
            }
        }
        printf("%s\n",scc==1?"Yes":"No");
    }
    return 0;
}